package lerry.nape.body;

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import lerry.nape.utils.DisplayObjectISO;

import nape.geom.AABB;
import nape.geom.GeomPoly;
import nape.geom.GeomPolyList;
import nape.geom.Vec2;
import nape.phys.Body;
import nape.phys.BodyType;
import nape.phys.Compound;
import nape.shape.Polygon;
import nape.space.Space;
import nape.geom.MarchingSquares;

/**
 * ...
 * @author ...lxq
 */
class CustomBody{
	private var dobj:DisplayObject;
	private var re:Body;
	private var iso:DisplayObjectISO;
	public function new(obj:DisplayObject,space:Space=null,cellSize:UInt=4,quality:UInt=8,useGraphic:Bool=true,graphicContainer:DisplayObjectContainer=null) {
		dobj=obj;
		iso=new DisplayObjectISO(obj);
		run(Vec2.weak(cellSize, cellSize),quality);
		if (space != null) {
			re.space = space;
		}
		if(useGraphic){
			re.userData.graphic=obj;
			re.userData.graphicOffset = Vec2.get( -obj.width / 2, -obj.height / 2);
			if(graphicContainer!=null){
				graphicContainer.addChild(obj);
			}	
		}

	}
	private function run(cell:Vec2=null,quality:Int=5,simplification:Float=1.5):Void {
		re = new Body();
		if(cell == null){
			cell = Vec2.weak(8, 8);
		}
		var polys:GeomPolyList;
		#if flash
			polys = MarchingSquares.run(iso, iso.bounds, cell, quality);
		#else 
			polys = MarchingSquares.run(iso.iso, iso.bounds, cell, quality);
		#end
		polys.foreach(function(p:GeomPoly):Void{
			var gs:GeomPolyList=p.simplify(simplification).convexDecomposition();
			gs.foreach(function(g:GeomPoly):Void {
				re.shapes.add(new Polygon(g));
				g.dispose();
			});
			p.dispose();
			gs.clear();
		});
		polys.clear();
		re.align();
		return ;
	}
	public var type(get_type, set_type):BodyType;
	function get_type():BodyType {
		return result.type;
	}
	function set_type(value:BodyType):BodyType {
		return result.type = value;
	}
	
	public var space(get_space, set_space):Space;
	function get_space():Space {
		return result.space;
	}
	function set_space(value:Space):Space {
		return result.space = value;
	}
	
	public var result(get_result, null):Body;
	function get_result():Body {
		return re;
	}
	
	
}